/*
 * PhotonRTOS础光实时操作系统 -- 保护测试代码
 *
 * Copyright (C) 2023 国科础石(重庆)软件有限公司
 *
 * 作者: Lin Yang <s-yanglin@kernelsoft.com>
 *
 * License terms: GNU General Public License (GPL) version 3
 *
 */

#include "../utest.h"

#if defined(AUTOSAR_MEMORY_PROTECTION)
TEST(CheckISRMemoryAccess)
{
	VAR(AccessType, AUTOMATIC) access_type;
	/**
	 * [SWS_Os_00267] ⌈如果	ISR 引用 <ISRID> 在调用CheckISRMemoryAccess()时有效， CheckISRMemoryAccess()将返回 ISR 对指定内存区域的访问权限。 ⌋ ( )
	 */
	access_type = CheckISRMemoryAccess(0, (void *)0x0, 0);
	ASSERT_EQ(access_type, (OSMEMORY_IS_READABLE | OSMEMORY_IS_WRITEABLE));

	/**
	 * [SWS_Os_00313] ⌈如果访问权限（例如“读取”）对于在CheckISRMemoryAccess()调用中指定的整个内存区域无效，则CheckISRMemoryAccess()将不会产生与此权限相关的访问权限。 ⌋ ( )
	 */
	access_type = CheckISRMemoryAccess(0, (void *)0xffffffff, 10);
	ASSERT_EQ(access_type, OSMEMORY_IS_UNACCESSABLE);

	/**
	 * [SWS_Os_00268] 如果 ISR 引用 <ISRID> 无效， CheckISRMemoryAccess()将返回无访问权限。 ⌋ ( )
	 */
	access_type = CheckISRMemoryAccess(-1, (void *)0x0, 0);
	ASSERT_EQ(access_type, OSMEMORY_IS_UNACCESSABLE);
}

TEST(CheckTaskMemoryAccess)
{
	VAR(AccessType, AUTOMATIC) access_type;
	/**
	 * [SWS_Os_00267] ⌈如果	TASK 引用 <TASKID> 在调用CheckTaskMemoryAccess()时有效， CheckTaskMemoryAccess()将返回 TASK 对指定内存区域的访问权限。 ⌋ ( )
	 */
	access_type = CheckTaskMemoryAccess(0, (void *)0x0, 0);
	ASSERT_EQ(access_type, OSMEMORY_IS_READABLE | OSMEMORY_IS_WRITEABLE);

	/**
	 * [SWS_Os_00313] ⌈如果访问权限（例如“读取”）对于在CheckTaskMemoryAccess()调用中指定的整个内存区域无效，则CheckTaskMemoryAccess()将不会产生与此权限相关的访问权限。 ⌋ ( )
	 */
	access_type = CheckTaskMemoryAccess(0, (void *)0xffffffff, 10);
	ASSERT_EQ(access_type, OSMEMORY_IS_UNACCESSABLE);

	/**
	 * [SWS_Os_00268] 如果 TASK 引用 <TASKID> 无效， CheckTaskMemoryAccess()将返回无访问权限。 ⌋ ( )
	 */
	access_type = CheckTaskMemoryAccess(-1, (void *)0x0, 0);
	ASSERT_EQ(access_type, OSMEMORY_IS_UNACCESSABLE);
}
#endif /* defined(AUTOSAR_MEMORY_PROTECTION) */

#if defined(AUTOSAR_OS_APPLICATION)
TEST(CheckObjectAccess)
{
	VAR(ObjectAccessType, AUTOMATIC) status;
	/**
	 * [SWS_Os_00271 ] ⌈如果调用CheckObjectAccess()中的 OS-Application <ApplID>有权访问查询的对象，CheckObjectAccess()应返回ACCESS 。 ⌋ ( )
	 */
	status = CheckObjectAccess(0, TYPE_COUNTER, &autosar_counters[0].object);
	ASSERT_EQ(status, ACCESS);
	/**
	 * [SWS_Os_00272] ⌈如果调用CheckObjectAccess()中的 OS-Application <ApplID>无权访问查询的对象，CheckObjectAccess()应返回NO_ACCESS 。 ⌋ ( )
	 */
	/**
	 * [SWS_Os_00423] ⌈如果在CheckObjectAccess()调用中要检查的对象不是有效对象或 <ApplID> 无效或 <ObjectType> 无效，则CheckObjectAccess()应返回NO_ACCESS 。 ⌋ ( )
	 */
	status = CheckObjectAccess(0, TYPE_COUNTER, NULL);
	ASSERT_EQ(status, NO_ACCESS);

	status = CheckObjectAccess(2, TYPE_COUNTER, &autosar_counters[0].object);
	ASSERT_EQ(status, NO_ACCESS);

	status = CheckObjectAccess(0, TYPE_ALARM, &autosar_counters[0].object);
	ASSERT_EQ(status, NO_ACCESS);

	/**
	 * [SWS_Os_00519] ⌈ CheckObjectAccess()的可用性：在可伸缩性等级 3 和 4 中可用。⌋ ( )
	 */


}

/**
 * [SWS_Os_00547] ⌈ AllowAccess ()的可用性：在可伸缩性等级 3 和 4 中可用。⌋ ( )
 */
TEST(AllowAccess)
{
	VAR(StatusType, AUTOMATIC) status;
	/**
	 * [SWS_Os_00497] ⌈如果AllowAccess()调用者的 OS-Application 状态不是APPLICATION_RESTARTING AllowAccess()应返回E_OS_STATE。 ⌋ ( )
	 * [SWS_Os_00498] ⌈如果 AllowAccess() 调用者的 OS-Application 状
	 * 态为APPLICATION_RESTARTING ， AllowAccess ()应将状态设置为
	 * APPLICATION_ACCESSIBLE并允许其他 OS-Applications 访问调用者
	 *  OS-Application 的配置对象。 ⌋ ( )
	 */
	status = AllowAccess();
	ASSERT_EQ(status, E_OS_STATE);

}

TEST(CheckObjectOwnership)
{
	VAR(ApplicationType, AUTOMATIC) status;
	/**
	 * [SWS_Os_00273] ⌈如果在CheckObjectOwnership()调用中指定的对象 ObjectType存在， CheckObjectOwnership()将返回该对象所属的 OS-Application 的标识符。 ⌋ ( )
	 */
	status = CheckObjectOwnership(TYPE_COUNTER, &autosar_counters[0].object);
	ASSERT_EQ(status, autosar_counters[0].object.app_id);

	/**
	 * [SWS_Os_00274] ⌈如果在CheckObjectOwnership()调用中指定的对象 ObjectType 无效或类型的参数（“...”）无效或对象不属于任何 OS-Application， CheckObjectOwnership()应返回INVALID_OSAPPLICATION . ⌋ ( )
	 */
	status = CheckObjectOwnership(99, &autosar_counters[0].object);
	ASSERT_EQ(status, INVALID_OSAPPLICATION);

	status = CheckObjectOwnership(TYPE_COUNTER, &autosar_schedule_tables[0].object);
	ASSERT_EQ(status, INVALID_OSAPPLICATION);

	/**
	 * [SWS_Os_00520] ⌈ CheckObjectOwnership()的可用性：可用于可扩展性等级 3 和 4 以及多核系统。 ⌋ ( )
	 */


}
#endif /* defined(AUTOSAR_OS_APPLICATION) */

#if defined(AUTOSAR_TRUSTED_FUNCTION)
TEST(CallTrustedFunction)
{
	VAR(StatusType, AUTOMATIC) status;

#if defined(EXTENDED_STATUS)
	/**
	 * FunctionIndex >= MAX_TRUSTED_FUNC_NUM
	 */
	status = CallTrustedFunction(MAX_TRUSTED_FUNC_NUM, NULL);
	ASSERT_EQ(status, E_OS_SERVICEID);
	/**
	 *  autosar_trusted_func[FunctionIndex].trusted_func == NULL
	 */
	status = CallTrustedFunction(2, NULL);
	ASSERT_EQ(status, E_OS_SERVICEID);

	/**
	 * autosar_os_app[caller_app_id].core_id != autosar_os_app[func_app_id].core_id
	 */
	status = CallTrustedFunction(1, NULL);
	ASSERT_EQ(status, E_OS_SERVICEID);
#endif

	/**
	 * [SWS_Os_00265] ⌈ 如果 <FunctionIndex> 是一个定义的函数索引， CallTrustedFunction()将调用函数 <FunctionIndex> 从实现特定可信函数列表中使用提供可信函数的 OSApplication 的保护设置，并在完成后返回E_OK 。 ⌋ ( )
	 */
	status = CallTrustedFunction(0, NULL);
	ASSERT_EQ(status, E_OK);
}
#endif /* defined(AUTOSAR_TRUSTED_FUNCTION) */


TEST_SUIT(Protection)
{
#if defined(AUTOSAR_MEMORY_PROTECTION)
	/* FIXME: kernel_text_start, kernel_text_end无效导致测试不通过 */
	UTEST_CASE(CheckISRMemoryAccess);
	UTEST_CASE(CheckTaskMemoryAccess);
#endif

#if defined(AUTOSAR_OS_APPLICATION)
	UTEST_CASE(CheckObjectAccess);
	UTEST_CASE(AllowAccess);
	UTEST_CASE(CheckObjectOwnership);
#endif /* defined(AUTOSAR_OS_APPLICATION) */

#if defined(AUTOSAR_TRUSTED_FUNCTION)
	UTEST_CASE(CallTrustedFunction);
#endif /* defined(AUTOSAR_TRUSTED_FUNCTION) */
}

